package com.lambkit.module.upms.shiro;

import java.io.Serializable;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.mgt.RealmSecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.subject.Subject;

import com.jfinal.kit.StrKit;
import com.jfinal.log.Log;
import com.lambkit.module.upms.client.shiro.UpmsRealm;

public class ShiroAuthorizationKit {
	private static Log log = Log.getLog(ShiroAuthorizationKit.class);
	
	 /**
     * 获得会话
     * @return
     */
    public static Session getSession() {
        return getSubject().getSession();
    }

    /**
     * 获得登录的主体 每次请求都会创建一个新的主体
     * @return
     */
    public static Subject getSubject() {
        return SecurityUtils.getSubject();
    }
	
	/**
	 * 清除所有用户的缓存，这个可以用
	 */
	public static void clearCachedAuth() {
		RealmSecurityManager realmMgr = (RealmSecurityManager) SecurityUtils.getSecurityManager();
		UpmsRealm realm = (UpmsRealm) realmMgr.getRealms().iterator().next();
		Cache<Object, AuthorizationInfo> authorizationCache  = realm.getAuthorizationCache();
        if (authorizationCache != null) {
//        	for (Object key : authorizationCache.keys()) {
//        		SimplePrincipalCollection principals = (SimplePrincipalCollection) key;
//        		for (String realmName : principals.getRealmNames()) {
//        			System.out.println("--------彻底清除[授权]缓存: realmName=" + realmName);
//					for (Object object : principals.fromRealm(realmName)) {
//						System.out.println("--------彻底清除[授权]缓存: " + object + ", " + object.getClass().getName());
//					}
//				}
//				
//			}
            authorizationCache.clear();
            System.out.println("彻底清除[授权]缓存..............");
        }
	}
	
	/**
	 * 彻底清空指定用户的身份认证缓存 针对于修改密码 退出登录，这个可以用
	 * @param username
	 */
	public static void clearCachedAuth(String username) {
		RealmSecurityManager realmMgr = (RealmSecurityManager) SecurityUtils.getSecurityManager();
		UpmsRealm realm = (UpmsRealm) realmMgr.getRealms().iterator().next();
		Cache<Object, AuthorizationInfo> authorizationCache  = realm.getAuthorizationCache();
        if (authorizationCache != null) {
        	//myRealm和shiro.ini中定义的变量名称一致myRealm=com.lambkit.module.upms.shiro.UpmsRealm
        	SimplePrincipalCollection principals = new SimplePrincipalCollection(username, "myRealm");
            authorizationCache.remove(principals);
            System.out.println("彻底清除[授权]缓存..............");
        }
	}
	
	/**
	 * 清除指定用户的缓存
	 */
//	public static void clearCachedAuthorizationInfo(String username) {
//		Subject subject = SecurityUtils.getSubject();   
//		UpmsUser user = UpmsManager.me().getUpmsApiService().selectUpmsUserByUsername(username);
//		//获取指定用户的User对象，构造SimplePrincipalCollection，然后将当前subject伪装成指定用户，然后再进行缓存清除
//		//myRealm和shiro.ini中定义的变量名称一致myRealm=com.lambkit.module.upms.shiro.UpmsRealm
//        SimplePrincipalCollection principals = new SimplePrincipalCollection(user, "myRealm");
//        subject.runAs(principals);
//        RealmSecurityManager rsm = (RealmSecurityManager)SecurityUtils.getSecurityManager();
//        UpmsRealm authRealm = (UpmsRealm) rsm.getRealms().iterator().next();
//        authRealm.clearCachedAuthorization(subject.getPrincipals());
//        subject.releaseRunAs();
//	}

	/**
	 * 清除用户的授权信息，无用
	 * 
	 * @param username
	 */
	public static void clearAuthorizationInfo(String username) {
		if (log.isDebugEnabled()) {
			log.debug("clear the " + username + " authorizationInfo");
		}
		RealmSecurityManager realmMgr = (RealmSecurityManager) SecurityUtils.getSecurityManager();
		CacheManager cacheManager = realmMgr.getCacheManager();
		// ShiroCasRealm.authorizationCache 为shiro自义cache名(shiroCasRealm为我们定义的reaml类的类名)
		Cache<Object, Object> cache = cacheManager.getCache("myRealm.authorizationCache");
		cache.remove(username);
	}

	/**
	 * 清除当前用户的授权信息
	 */
	public static void clearAuthorizationInfo() {
		if (SecurityUtils.getSubject().isAuthenticated()) {
			Subject subject = SecurityUtils.getSubject();
			String username = (String) subject.getPrincipal();
			if (StrKit.notBlank(username)) {
				clearAuthorizationInfo(username);
			}
		}
	}

	/**
	 * 清除session(认证信息) @param JSESSIONID
	 */

	public static void clearAuthenticationInfo(Serializable JSESSIONID) {
		if (log.isDebugEnabled()) {
			log.debug("clear the session " + JSESSIONID);
		}
		RealmSecurityManager realmMgr = (RealmSecurityManager) SecurityUtils.getSecurityManager();
		CacheManager cacheManager = realmMgr.getCacheManager();
		// shiro-activeSessionCache
		// 为shiro自义cache名，该名在org.apache.shiro.session.mgt.eis.CachingSessionDAO抽象类中定义
		// 如果要改变此名，可以将名称注入到sessionDao中，例如注入到CachingSessionDAO的子类EnterpriseCacheSessionDAO类中
		Cache<Object, Object> cache = cacheManager.getCache("shiro-activeSessionCache");
		cache.remove(JSESSIONID);
	}

}
